import React, {CSSProperties, Fragment, ReactNode, useEffect, useRef, useState} from 'react';
import {Demand, DemandDetails} from './data.d';
import {modulesUrl} from "@/assets/constant/modulesUrl";
import {dateFormat, deleteConfirm, downloadFile, hooksSet} from "@/assets/utils/utils";
import {get} from "@/assets/service/baseService";
import {history, useRequest} from 'umi';
import {Button, Card, Descriptions, Form, InputNumber, message, Modal, Select, Space, Steps} from "antd";
import {
  annexList,
  deleteAnnexByIds,
  detailsList,
  findCanFlowUserList,
  flow,
  saveAnnex,
  startAndIssue
} from "@/pages/demand/DemandList/service";
import ProTable, {ActionType} from '@ant-design/pro-table';
import {ProFormDateTimePicker, ProFormText, ProFormTextArea} from "@ant-design/pro-form";
import {GridContent, PageContainer, RouteContext} from "@ant-design/pro-layout";
import {UserOutlined} from "@ant-design/icons";
import formStyles from './style.less';
import {User} from "@/pages/sys/UserList/data";
import {Link} from "react-router-dom";
import {Annex} from "@/pages/sys/AnnexList/data";
import Upload from "@/assets/components/upload";
import {breadcrumbItemRender} from "@/assets/components/tableList";

const DemandForm: React.FC<{}> = (props) => {

  // @ts-ignore
  const demandId = props.match.params.id;
  // @ts-ignore
  const type = props.match.params.type;

  const [form] = Form.useForm();
  const annexActionRef = useRef<ActionType>();
  /**
   * 上一个页面
   */
  const prev = '/demand/demand/' + type;

  /**
   * 当前流程是否在登录用户手中
   */
  let [nowFlowIsCurrentUser, setNowFlowIsCurrentUser] = useState(false);
  /**
   * 当前用户
   */
  let [currentUser, setCurrentUser] = useState<any>();
  /**
   * 用户必填
   */
  const [userRequired, setUserRequired] = useState(false)

  /**
   * 流程step
   */
  const [steps, setSteps] = useState()
  /**
   * 需求实体
   */
  const [demand, setDemand] = useState<Demand>()
  const getDemandRun = useRequest(() => get(modulesUrl.demandDemand, demandId), {
    manual: true,
    onSuccess: (result: Demand, params) => {
      hooksSet(setDemand, result, () => {
        // 判断当前流程是否在登录用户手中
        setNowFlowIsCurrentUser(result?.nowUserId === result?.currentUser?.id)
        // 插入当前登录用户
        setCurrentUser(result?.currentUser)
        // 获取详情列表
        getDemandDetailsListRun()
        // 获取可选择用户select列表
        findCanFlowUserListRun(result.id)
      })
    }
  }).run
  /**
   * 获取需求详情列表
   */
  const getDemandDetailsListRun = useRequest(() => detailsList(demandId), {
    manual: true,
    onSuccess: (result, params) => {
      hooksSet(setSteps, getStep(result))
    }
  }).run

  /**
   * 获取可选择用户select列表
   */
  const [canFlowUserSelectList, setCanFlowUserSelectList] = useState([]);
  const findCanFlowUserListRun = useRequest((id?: string) => findCanFlowUserList(id), {
    manual: true,
    onSuccess: (result, params) => {
      if (result && result.length > 0) {
        let list: any = []
        result.forEach((user: User) => {
          list.push({label: user.name, value: user.id})
        })
        setCanFlowUserSelectList(list);
      }
      // @ts-ignore 关闭弹框
      params[1] && params[1]();
    }
  }).run

  /**
   * 开始并直接到待审核
   */
  const handleStartAndIssue = async (id: string) => {
    const hide = message.loading('正在开始流程');
    try {
      await startAndIssue(id);
      hide();
      message.success("开始成功！")
      history.push(prev);
      return true;
    } catch (error) {
      console.log(error)
      hide();
      message.error('开始失败，请重试');
      return false;
    }
  };

  /**
   * 流程流转
   * @param makeType 操作类型
   */
  const handleFlow = async (makeType: string) => {
    let messageHead = makeType === "4" ? "关闭" : "流转"
    const hide = message.loading('正在' + messageHead);
    // 如果是正常提交或当前流程为退回，则都需要用户必填
    if (makeType === "1" && demand?.status !== "5") {
      setUserRequired(true)
    } else {
      setUserRequired(false)
    }
    form.validateFields().then(async () => {
      try {
        let params = form.getFieldsValue();
        params["demand.id"] = demand?.id
        params["makeType"] = makeType
        await flow(params);
        hide();
        message.success(messageHead + "成功！")
        history.push(prev);
        window.location.reload()
        return true;
      } catch (error) {
        console.log(error)
        hide();
        message.error(messageHead + '失败，请重试');
        return false;
      }
    }).catch(() => {
      hide();
    })
  };

  /**
   * 获取step
   * @flowStatus 流程状态
   */
  const getStep: any = (demandDetailsList: DemandDetails[]) => {
    let description: ReactNode[] = [];
    let endDate: any[] = [];
    // 记录已存在的流程和在description的位置，形式为：流程状态字符串-description下标
    let record: string[] = [];
    // 如果是驳回，则需取到上一个流程
    let lastDemandDetails: DemandDetails;
    if (demand?.flowStatus === "7") {
      lastDemandDetails = demandDetailsList[demandDetailsList.length - 2];
    }
    // 详情列表是按流程排序查询的，所以直接遍历插入就行
    let index: number = 0;
    demandDetailsList?.forEach((demandDetails) => {
      let flowStatus: string | undefined = demandDetails.demandFlowStatus;
      // 筛掉驳回
      if (flowStatus !== "7") {
        // 驳回后，重新回归流程，会存在两个相同流程，取最后一个
        // 查看record里，本流程是否已存储
        let isHave: boolean = false;
        let descriptionIndex: number = 0;
        if (record.length > 0) {
          record.forEach((r) => {
            let rs = r.split("-");
            if (rs[0] === flowStatus) {
              isHave = true;
              descriptionIndex = parseInt(rs[1]);
              return
            }
          })
        }
        // 如果有覆盖原纪录，没有则直接push
        if (isHave) {
          description[descriptionIndex] = <div style={{color: "rgb(140,140,140)"}}>
            <Fragment>
              {demandDetails?.user?.name}
              <UserOutlined style={{marginLeft: 8}}/>
            </Fragment>
            {/*{demandDetails.endDate ?*/}
            {/*  <div>{dateFormat(demandDetails?.endDate)}</div> : undefined}*/}
          </div>
          endDate[descriptionIndex] = dateFormat(demandDetails?.endDate);
        } else {
          description.push(
            <div style={{color: "rgb(140,140,140)"}}>
              <Fragment>
                {demandDetails?.user?.name}
                <UserOutlined style={{marginLeft: 8}}/>
              </Fragment>
              {/*{demandDetails.endDate ?*/}
              {/*  <div>{dateFormat(demandDetails?.endDate)}</div> : undefined}*/}
            </div>
          )
          endDate.push(dateFormat(demandDetails?.endDate));
          // 记录本次储存的流程
          record.push(flowStatus + "-" + index)
          ++index;
        }
      }
    })
    return <RouteContext.Consumer>
      {({isMobile}) => (
        <Steps
          direction={isMobile ? 'vertical' : 'horizontal'}
          progressDot={customDot}
          current={demand?.flowStatus === "7" ? (parseInt(lastDemandDetails?.demandFlowStatus as string)) - 1 : (parseInt(demand?.flowStatus as string) - 1)}
          status={demand?.flowStatus === "7" ? "error" : "process"}
        >
          <Steps.Step title="已提交" subTitle={endDate.length > 0 ? endDate[0] : undefined}
                      description={description[0]}/>
          <Steps.Step title="待审核" subTitle={endDate.length > 1 ? endDate[1] : undefined}
                      description={description.length > 1 ? description[1] : undefined}/>
          <Steps.Step title="待分派" subTitle={endDate.length > 2 ? endDate[2] : undefined}
                      description={description.length > 2 ? description[2] : undefined}/>
          <Steps.Step title="待处理" subTitle={endDate.length > 3 ? endDate[3] : undefined}
                      description={description.length > 3 ? description[3] : undefined}/>
          <Steps.Step title="待完成" subTitle={endDate.length > 4 ? endDate[4] : undefined}
                      description={description.length > 4 ? description[4] : undefined}/>
          <Steps.Step title="已完成" />
        </Steps>
      )}
    </RouteContext.Consumer>
  }

  const customDot = (dot: React.ReactNode, {}: { status: string; },) => {
    return dot;
  };

  /**
   * 启动加载
   */
  useEffect(() => {
    getDemandRun()
  }, []);

  /**
   * 样式
   */
    // const cardHeadStyle: CSSProperties = {fontWeight: "bold"};
  const cardHeadStyle: CSSProperties = {};

  /**
   * 关闭需求按钮
   */
  const closeDemandButton = () => {
    let result;
    // 草稿、流程为已提交、退回，且当前登录用户为本需求的创建者
    if ((demand?.status === "1" || demand?.flowStatus === "1" || demand?.status === "5") && demand?.createBy === demand?.currentUser?.id) {
      result = <Button type={"primary"} onClick={() => Modal.confirm({
        title: '关闭需求',
        content: '确定关闭吗？',
        okText: '确认',
        cancelText: '取消',
        onOk: () => handleFlow("4"),
      })}>关闭需求</Button>;
    }
    return result;
  }

  return (
    <PageContainer
      title={"需求详情"}
      header={{
        breadcrumb: {
          routes: [
            {
              path: prev,
              breadcrumbName: '需求列表',
            },
            {
              path: '',
              breadcrumbName: '需求详情',
            }
          ],
          itemRender: breadcrumbItemRender
        }
      }}
    >
      <div className={formStyles.main}>
        <GridContent>
          <Card title="流程进度" headStyle={cardHeadStyle} style={{marginBottom: 24}}>
            {steps}
          </Card>
          <Card title="基本信息" headStyle={cardHeadStyle} style={{marginBottom: 24}}>
            <Descriptions style={{marginBottom: 16}} column={3} size={"middle"} bordered>
              <Descriptions.Item labelStyle={{width: "100px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="需求名称">{demand?.name}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="需求类型">{demand?.type?.name}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="预计工时（小时）">{demand?.estimateWorkingHours}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="实际工时（小时）">{demand?.actualWorkingHours ? demand?.actualWorkingHours : "-"}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="当前用户">{demand?.nowUser?.name}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="需求发起人">{demand?.createByUser?.name}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="创建时间">{dateFormat(demand?.createDate)}</Descriptions.Item>
              <Descriptions.Item labelStyle={{width: "150px", textAlign: "center"}} contentStyle={{width: "20%"}}
                                 label="预计完成时间">{demand?.estimateFinishDate ? dateFormat(demand?.estimateFinishDate) : "-"}</Descriptions.Item>
            </Descriptions>
          </Card>
          <Card title="需求说明" headStyle={cardHeadStyle} style={{marginBottom: 24}} extra={
            // 能编辑条件：为草稿或退回状态并且当前登录用户为创建人
            (demand?.status === "1" || demand?.status === "5") && demand.createBy === demand.currentUser?.id ?
              <Link to={"/demand/demand/" + type + "/edit/" + demand.id}><Button type={"primary"}>编辑</Button></Link> : undefined
          }>
            <div dangerouslySetInnerHTML={{__html: demand?.description || ""}}></div>
          </Card>
          <Card title="需求附件" headStyle={cardHeadStyle} style={{marginBottom: 24}} extra={
            // 当前流程需要为自己
            nowFlowIsCurrentUser && demand?.status !== "4" ?
              <Upload
                name={"annexIds"}
                buttonType={"primary"}
                showUploadList={false}
                uploadSuccessCallback={({file, fileList}, annex) => {
                  const hide = message.loading('正在更新列表');
                  try {
                    saveAnnex(demandId, annex?.id);
                    hide();
                    message.success("更新列表成功！")
                    annexActionRef.current?.reload();
                    return true;
                  } catch (error) {
                    hide();
                    message.error('上传附件、更新列表失败，请重试');
                    return false;
                  }
                }}
              /> : undefined
          }>
            <ProTable
              columns={[
                {
                  title: '附件名称',
                  dataIndex: 'name',
                },
                {
                  title: '操作',
                  valueType: 'option',
                  fixed: 'right',
                  render: (_: any, record: Annex) => (
                    [
                      <a onClick={() => downloadFile(record?.id, record?.name)}>下载</a>,
                      // 如果流程在当前登录用户手上，且附件为当前登录用户上传，则可以删除
                      nowFlowIsCurrentUser && record?.createBy === currentUser.id ?
                        <a onClick={() => deleteConfirm(async () => {
                          const hide = message.loading('正在删除');
                          try {
                            await deleteAnnexByIds(demandId, record?.id);
                            hide();
                            message.success("删除成功！")
                            annexActionRef.current?.reload();
                            return true;
                          } catch (error) {
                            console.log(error)
                            hide();
                            message.error('删除失败，请重试');
                            return false;
                          }
                        })}>删除</a> : undefined,
                    ]
                  ),
                }
              ]}
              request={() => annexList(demandId)}
              rowKey="id"
              pagination={{
                showQuickJumper: true,
              }}
              actionRef={annexActionRef}
              search={false}
              toolBarRender={false}
            /></Card>
          <Card title="流程信息" headStyle={cardHeadStyle} style={{marginBottom: 24}} bordered={false}>
            <ProTable
              columns={[
                {
                  title: '流程环节',
                  dataIndex: 'flowStatusName',
                  width: 100,
                  // renderText: (_, record) => record.demandFlowStatusName,
                },
                {
                  title: '处理人',
                  width: 100,
                  dataIndex: 'userName',
                  renderText: (_, record) => record.user?.name,
                },
                {
                  title: '到达时间',
                  dataIndex: 'createDate',
                  width: 150,
                  renderText: (text) => dateFormat(text),
                },
                {
                  title: '处理时间',
                  dataIndex: 'endDate',
                  width: 150,
                  renderText: (text) => dateFormat(text),
                },
                {
                  title: '选择决策',
                  dataIndex: 'makeTypeName',
                },
                {
                  title: '处理意见',
                  dataIndex: 'description',
                },
              ]}
              request={() => detailsList(demandId)}
              rowKey="id"
              pagination={{
                showQuickJumper: true,
              }}
              toolBarRender={false}
              search={false}
            />
          </Card>
          {/* 当为已关闭或已完成或登录用户不为nowUser时，不显示流程办理 */}
          {
            // 如果是草稿，显示开始开始流程按钮和返回
            (
              demand?.status === "1" && demand?.nowUserId === demand?.currentUser?.id ? (
                  <Form.Item style={{textAlign: "right"}}>
                    <Space>
                      <Button id="return">
                        <Link to={prev}>返回</Link>
                      </Button>
                      <Button type={"primary"} id="return" onClick={() => handleStartAndIssue(demandId)}>
                        需求提交
                      </Button>
                      {closeDemandButton()}
                    </Space>
                  </Form.Item>
                ) :
                ((
                    demand?.flowStatus !== "0" &&
                    demand?.flowStatus !== "6" &&
                    demand?.nowUserId === demand?.currentUser?.id
                  )
                    ?
                    <Card title="流程办理" headStyle={cardHeadStyle}>
                      <Form
                        layout={"vertical"}
                        form={form}
                        preserve={false}
                      >
                        {/* 待分派时，需要填入预估工时或预估完成时间 */}
                        {
                          demand?.flowStatus === "3" ?
                            <ProFormText name="demand.estimateWorkingHours" label="预估工时（小时）" placeholder="请输入预估工时"
                                         rules={[{required: true, message: '预估工时为必填项',}]}
                                         initialValue={demand.estimateWorkingHours}/>
                            : undefined
                        }
                        {
                          demand?.flowStatus === "3" ?
                            <ProFormDateTimePicker name="demand.estimateFinishDate" label="预估完成时间（退回、处理退回时，无需填写）"
                                                   rules={[{required: userRequired, message: '预估完成时间为必选项',}]}/>
                            : undefined
                        }
                        {/* 当前流程为待处理或待完成或退回时，不用选择用户 */}
                        {
                          demand?.flowStatus !== "4" && demand?.flowStatus !== "5" && demand?.flowStatus !== "7" ?
                            <Form.Item key="userId" name="userId" label="选择用户"
                                       rules={[{required: userRequired, message: '用户为必选项',}]}>
                              <Select showSearch placeholder={"请选择用户（退回、处理退回时，无需选择）"}
                                      optionFilterProp={"label"}
                                      options={canFlowUserSelectList}>
                              </Select>
                            </Form.Item> : undefined
                        }
                        {/* 当前流程为待处理，可以填写实际工时，默认为预估工时 */}
                        {
                          demand?.flowStatus === "4" ?
                            <Form.Item key="demand.actualWorkingHours" name="demand.actualWorkingHours"
                                       initialValue={demand.estimateWorkingHours} label="实际工时（小时）"
                                       rules={[{required: true, message: '用户为必选项',}]}>
                              <InputNumber placeholder="请输入实际工时" style={{width: "100%"}}/>
                            </Form.Item>
                            : undefined
                        }
                        <ProFormTextArea key="description" name="description" label="描述"
                                         placeholder="请输入描述"
                                         rules={[{required: true, message: '描述为必填项',}]}/>
                        <Form.Item style={{textAlign: "right"}}>
                          <Space>
                            <Button><Link to={prev}>返回</Link></Button>
                            {/* 可确定的情况（即正常流转）：流程状态为草稿、待审核、待分派、驳回 */}
                            {
                              (
                                demand?.status === "1" ||
                                demand?.flowStatus === "7" ||
                                demand?.flowStatus === "1" ||
                                demand?.flowStatus === "2" ||
                                demand?.flowStatus === "3"
                              ) && demand?.nowUserId === demand?.currentUser?.id ?
                                <Button type={"primary"} onClick={() => handleFlow("1")} value={"1"}>提交</Button> : ""
                            }
                            {/* 可完成提交的情况：流程状态为待处理 */}
                            {demand?.flowStatus === "4" && demand?.nowUserId === demand?.currentUser?.id ?
                              <Button type={"primary"} onClick={() => handleFlow("2")}>完成</Button> : ""}
                            {/* 只有一种情况可确定完成需求：流程状态为待完成 */}
                            {demand?.flowStatus === "5" && demand?.nowUserId === demand?.currentUser?.id ?
                              <Button type={"primary"} onClick={() => handleFlow("3")}>确定完成</Button> : ""}
                            {/* 可驳回的情况：流程状态为待审核、待分派、待处理、待完成 */}
                            {(demand?.flowStatus === "2" || demand?.flowStatus === "3" || demand?.flowStatus === "4" || demand?.flowStatus === "5") && demand?.nowUserId === demand?.currentUser?.id ?
                              <Button type={"primary"} onClick={() => Modal.confirm({
                                title: '退回',
                                content: '确定退回吗？',
                                okText: '确认',
                                cancelText: '取消',
                                onOk: () => handleFlow("0")
                              })}>退回</Button> : ""}
                            {closeDemandButton()}
                          </Space>
                        </Form.Item>
                      </Form>
                    </Card>
                    :
                    <Form.Item style={{textAlign: "right"}}>
                      <Button id="return">
                        <Link to={prev}>返回</Link>
                      </Button>
                    </Form.Item>
                )
            )
          }
        </GridContent>
      </div>
    </PageContainer>
  );
};

export default DemandForm;
